package main.java.DMDE.controllers;

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import javax.swing.JFrame;

import main.java.DMDE.infrastructure.IProjectContext;
import main.java.DMDE.controllers.listeners.IRelationshipEventListener;
import main.java.DMDE.model.Attribute;
import main.java.DMDE.model.CardinalityValues;
import main.java.DMDE.model.Diagram;
import main.java.DMDE.model.Entity;
import main.java.DMDE.model.Method;
import main.java.DMDE.model.Modifier;
import main.java.DMDE.model.Type;
import main.java.DMDE.model.Visibility;
import main.java.DMDE.model.relationships.FactoryRelationship;
import main.java.DMDE.model.relationships.Relationship;
import main.java.DMDE.model.relationships.RelationshipComponent;
import main.java.DMDE.model.relationships.RelationshipTypes;
import main.java.DMDE.view.IRelationshipView;
import main.java.ERMDE.infrastructure.IterableExtensions;

public class RelationshipController extends BaseController implements
	IRelationshipController {

    private Relationship pendingRelationship;
    private List<Relationship> pendingRelationships;
    private IRelationshipView view;
    private List<IRelationshipEventListener> listeners;
    private Diagram diagram;

    public RelationshipController(IProjectContext projectContext,
	    IRelationshipView view) {
	super(projectContext);
	this.view = view;
	this.pendingRelationships = new ArrayList<Relationship>();
	this.listeners = new ArrayList<IRelationshipEventListener>();
    }

    @Override
    public void addCreateListener(IRelationshipEventListener listener) {
	listeners.add(listener);
    }

    @Override
    public void create() {
	view.setController(this);
	this.view.show();
    }

    @Override
    public void addDiagram(Diagram diagram) {
	this.diagram = diagram;
    }

    @Override
    public void createRelationship(String relationshipType) {
	pendingRelationship = FactoryRelationship.create(relationshipType,
		diagram,UUID.randomUUID());
	view.cleanEntities();
    }

    @Override
    public Relationship addRelationship() {
	RelationshipComponent relatCompA = getRelationshipComponentA();
	RelationshipComponent relatCompB = getRelationshipComponentB();
	if(relatCompA != null && relatCompB != null){
	    pendingRelationship.setComponentA(relatCompA);
	    pendingRelationship.setComponentB(relatCompB);
	    this.pendingRelationships.add(pendingRelationship);
	    return pendingRelationship;
	}
	return null;
    }

    @Override
    public boolean editRelationship(Relationship relationshipSelected) {
	RelationshipComponent relatCompA = getRelationshipComponentA();
	RelationshipComponent relatCompB = getRelationshipComponentB();
	if(relatCompA != null && relatCompB != null){
	    Relationship editedRelat = null; 
	    for(Relationship relat : this.pendingRelationships){
		if(relat.getId().equals(relationshipSelected.getId()))
		    editedRelat = relat;
	    }
	    if(editedRelat != null){
		editedRelat.setComponentA(relatCompA);
		editedRelat.setComponentB(relatCompB);
        	return true;
	    }
	}
	return false;
    }
    
    @Override
    public void createRelationship(Relationship relationship) {
	this.pendingRelationship = relationship;
	this.pendingRelationships.add(pendingRelationship);
	view.setController(this);
	view.setRelationship(relationship);
	this.view.show();
    }
    
    private RelationshipComponent getRelationshipComponentB() {
	if(pendingRelationship != null){
        	CardinalityValues min = view.getMinEntityB();
        	CardinalityValues max = view.getMaxEntityB();
        	String entityName = view.getEntityNameB();
        	Entity entity = pendingRelationship.getEntityWithName(entityName);
        	if(entity != null)
        	    return new RelationshipComponent(entity, min, max);
	}	
	return null;
    }

    private RelationshipComponent getRelationshipComponentA() {
	if(pendingRelationship != null){
    		CardinalityValues min = view.getMinEntityA();
    		CardinalityValues max = view.getMaxEntityA();
    		String entityName = view.getEntityNameA();
    		Entity entity = pendingRelationship.getEntityWithName(entityName);
    		if(entity != null)
    		    return new RelationshipComponent(entity, min, max);
	}	
	return null;
    }

    @Override
    public List<String> getEntitiesA() {
	return pendingRelationship.getEntitiesA();
    }

    @Override
    public List<String> getEntitiesB(String entityAName) {
	return pendingRelationship.getEntitiesB(entityAName);
    }

    @Override
    public List<Relationship> getRelationships() {
	return view.getRelationships();
    }

    @Override
    public void addRelationshipsToDiagram() throws Exception {
/*	if (this.pendingRelationship.getName() == null
		|| this.pendingRelationship.getName().equals(""))
	    throw new Exception("The field \"name\"  is not completed");

	if (this.relEntController.getRelationshipEntities().size() < 2)
	    throw new Exception(
		    "There should be at least two entities in a relationship");
*/
	for (IRelationshipEventListener listener : listeners)
	    listener.handleCreatedEvent(pendingRelationships);
	
    }

    @Override
    public boolean removeRelationship(Relationship relationshipSelected) {
	return pendingRelationships.remove(relationshipSelected);
    }

    @Override
    public void setDiagram(Diagram diagram) {
	this.diagram = diagram;
    }

}
